Skip to content

feat(cli): say when the process target stops matching (audit F17) - #67

Merged
donislawdev merged 1 commit into
masterfrom
fix/cli-says-when-the-target-stops-matching
Jul 28, 2026
Merged

feat(cli): say when the process target stops matching (audit F17)#67
donislawdev merged 1 commit into
masterfrom
fix/cli-says-when-the-target-stops-matching

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

What this closes (audit F17)

A process target that stops matching mid-run was invisible from the CLI. Measured
2026-07-28 on a real capture (elevated, real WinDivert), with the probe narrowed to
--target <pid> --dst-ip 8.8.8.8 --dst-port 53 --syn-drop 100 so nothing else on the
machine could be touched:

measured
target by PID, impaired 1 of 6 connections slipped, 5 timed out
same PID killed and restarted 5 of 5 fresh connections untouched, exit=OK
what the run said about it one line, printed at start, and nothing after
target by NAME, 3 lives x 4 connections OK FAIL FAIL FAIL in 3 of 3 lives

So the name path recovers on its own and a restart costs exactly one connection (the
one opened before the process owns any socket - the _pids limit F16 already documents).
The PID path never recovers, because that id is gone. Either way the CLI said nothing.

gui/app.py::_refresh_target re-reads the verdict on every tick and raises a banner, so
the blind spot was precisely on the CI/CD side (convention 18).

Change

  • _targeting_state(engine) + transition logging in _report_loop: warn on losing the
    target, info on getting it back. matched is a plain bool on the live
    ProcessTargeting - no lock, no syscall - so the loop asks on every pass. Sampled, not
    continuous, and the comment says so.
  • End of run: warn when a target was set, traffic was captured and nothing was in
    scope, plus In scope: X of Y captured packets in the text summary.
  • Guarded on seen: with nothing captured at all the capture filter is the story and
    --min-packets is the flag that tells it.

Deliberately not done

No new exit code, no --min-scoped. A target with no traffic of its own is a legitimate
run, and an assertion would change the exit-code contract under everyone already running
one. counters.scoped_seen is in the JSON summary for a pipeline that wants to assert on
it itself. The NDJSON sample schema (frozen contract) is untouched.

Verification

  • python -m pytest tests - 717 passed, 0 failed on an elevated shell (was 715).
  • python smoke_gui.py - OK.
  • Convention guards green (test_repo_conventions, test_cli_docs, test_code_hygiene,
    test_layering).
  • Five mutants, all caught, each on its intended assertion: transition logging removed;
    fired every pass instead of on change; zero-scope warning removed; its seen guard
    removed; the In scope line removed.

🤖 Generated with Claude Code

A targeted process that exits mid-run was invisible from the command line.
Measured 2026-07-28 on a real capture (elevated, real WinDivert, probe
narrowed to --target <pid> --dst-ip 8.8.8.8 --dst-port 53 --syn-drop 100):
the target was impaired correctly, then killed and restarted under a new
pid, after which 5 of 5 fresh connections went untouched - and the only
targeting line in the entire run was the one printed at start. Exit 0.

The GUI has always shouted about this (_refresh_target re-reads the verdict
on every tick), so the blind spot was exactly on the CI/CD side.

- _targeting_state(engine) plus transition logging in _report_loop: warn on
  losing the target, info on getting it back. Reading `matched` is a plain
  bool on the live ProcessTargeting, so the loop can ask on every pass.
- end of run: warn when a target was set, traffic was captured and nothing
  was in scope, plus an "In scope: X of Y captured packets" summary line.
  Guarded on `seen` - with no traffic at all the capture filter is the story
  and --min-packets is the flag that tells it.
- no new exit code and no new flag: a quiet target is a legitimate run, and
  an assertion would change the exit-code contract under existing users.
  The NDJSON sample schema is untouched; the new line is text-channel only.
- two guards in tests/test_cli_runtime.py, five mutants, all caught.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev donislawdev changed the title fix(cli): say when the process target stops matching (audit F17) feat(cli): say when the process target stops matching (audit F17) Jul 28, 2026
@donislawdev
donislawdev merged commit 2b3b5b3 into master Jul 28, 2026
8 checks passed
@donislawdev
donislawdev deleted the fix/cli-says-when-the-target-stops-matching branch July 28, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant